package com.panda.common.dao.mongo;

import java.util.List;
import java.util.regex.Pattern;

import org.bson.types.ObjectId;

import com.google.code.morphia.Datastore;
import com.google.code.morphia.Morphia;
import com.google.code.morphia.dao.BasicDAO;
import com.google.code.morphia.query.Query;
import com.mongodb.Mongo;
import com.panda.common.dao.page.PageBean;

public class MongoBaseDao extends BasicDAO<MongoBaseEntity, ObjectId> {
	
	/**
	 * 模糊查询标识
	 */
	public static final String FUZZY_QUERY_TYPE = "fuzzy";
	
	/**
	 * 精确查询标识
	 */
	public static final String EXACT_QUERY_TYPE = "exact";

	private Datastore ds;
	
	private Morphia morphia;
	
	private Mongo mongo;
	
	private String dbName;
	
	private String userName;
	
	private String userPwd;
	
	/**
	 * 默认一次查询最多为100条
	 */
	private Integer fetchSize = 100;

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public void setUserPwd(String userPwd) {
		this.userPwd = userPwd;
	}

	protected MongoBaseDao(Mongo mongo, Morphia morphia, String dbName) {
		super(mongo, morphia, dbName);
		this.morphia = morphia;
		this.mongo = mongo;
		this.dbName = dbName;
	}
	
	private void initDatastore(){
		if(ds==null){
			this.ds = morphia.createDatastore(this.mongo, this.dbName , this.userName, this.userPwd.toCharArray());
		}
	}

	public void saveOrUpdate(Object entity) {
		this.initDatastore();
		ds.save(entity);
	}

	@SuppressWarnings("unchecked")
	public List findAll(Class clazz) {
		this.initDatastore();
		return ds.find(clazz).asList();
	}

	/**
	 * 不带分页检索
	 * @param clazz
	 * @param queryParams
	 * @param queryType
	 * @param orderParam 排序参数 
	 * @return
	 */
	@SuppressWarnings( { "unchecked" })
	public List findQuery(Class clazz, List<MongoQueryParam> queryParams,String queryType,String orderParam) {
		Query query = null;
		if(FUZZY_QUERY_TYPE.equals(queryType)){//模糊检索
			query = this.createFuzzyQuery(clazz, queryParams).order(orderParam);
		}
		if(EXACT_QUERY_TYPE.equals(queryType)){//精确检索
			query = this.createExactQuery(clazz, queryParams).order(orderParam);
		}
		query.limit(fetchSize);
		return query.asList();
	}
	
	/**
	 * 根据查询条件返回query对象,然后可以根据query自定义个性化查询
	 * @param clazz
	 * @param queryParams
	 * @param queryType
	 * @param orderParam
	 * @return
	 */
	public Query findAndReturnQuery(Class clazz, List<MongoQueryParam> queryParams,String queryType,String orderParam){
		Query query = null;
		if(FUZZY_QUERY_TYPE.equals(queryType)){//模糊检索
			query = this.createFuzzyQuery(clazz, queryParams).order(orderParam);
		}
		if(EXACT_QUERY_TYPE.equals(queryType)){//精确检索
			query = this.createExactQuery(clazz, queryParams).order(orderParam);
		}
		return query;
	}
	


	@SuppressWarnings("unchecked")
	public Object findById(Class clazz, Object objectId) {
		this.initDatastore();
		Query query = ds.createQuery(clazz);
		query.filter("_id", objectId);
		List list = query.asList();
		if(list!=null){
			return list.get(0);
		}
		return null;
	}
	
	/**
	 * 更新某个对象
	 * @param object
	 */
	public void update(Object object) {
		this.initDatastore();
		ds.save(object);
	}
	
	/**
	 * 根据查询条件进行删除
	 * @param clazz
	 * @param title
	 * @param value
	 */
	@SuppressWarnings("unchecked")
	public void delete(Class clazz, List<MongoQueryParam> queryParams) {
		this.initDatastore();
		Query query = this.createFuzzyQuery(clazz, queryParams);
		ds.delete(query);
	}

	/**
	 * 删除所有数据
	 * @param clazz
	 */
	@SuppressWarnings("unchecked")
	public void deleteAll(Class clazz) {
		Query query = this.createQuery(clazz);
		ds.delete(query);
	}
	
	

	@SuppressWarnings("unchecked")
	public PageBean findQueryPage(Class clazz,List<MongoQueryParam> queryParams, PageBean pageBean,String queryType,String orderParam) {
		Query query = null;
		if(FUZZY_QUERY_TYPE.equals(queryType)){//模糊检索
			query = this.createFuzzyQuery(clazz, queryParams).order(orderParam);
		}
		if(EXACT_QUERY_TYPE.equals(queryType)){//精确检索
			query = this.createExactQuery(clazz, queryParams).order(orderParam);
		}
		if (pageBean != null) {
			query.limit(pageBean.getPageSize()).offset(
					(pageBean.getPageNow() - 1) * pageBean.getPageSize());
			pageBean.setTotalCount((int) query.countAll());
			pageBean.setResult(query.asList());
		}
		return pageBean;
	}
	
	
	@SuppressWarnings("unchecked")
	protected Query createNameQuery(Class clazz, String title, Object value) {
		this.initDatastore();
		return (Query) ds.createQuery(clazz).field(title).equal(value);
	}

	@SuppressWarnings("unchecked")
	protected Query createQuery(Class clazz) {
		this.initDatastore();
		return ds.createQuery(clazz);
	}
	
	/**
	 * 创建模糊检索query
	 * @param clazz
	 * @param queryParams
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private Query createFuzzyQuery(Class clazz,List<MongoQueryParam> queryParams){
		this.initDatastore();
		Query query = ds.createQuery(clazz);
		if(queryParams!=null){
			for(MongoQueryParam queryParam : queryParams){
				if(queryParam!=null && queryParam.getAttributeName()!=null){
					Pattern pattern = queryParam.getQueryPattern();
					if(pattern==null){
						pattern = Pattern.compile(queryParam.getQueryContent()+"",Pattern.CASE_INSENSITIVE);//忽略大小写
//						pattern = Pattern.compile("^.*" + queryParam.getAttributeName() + ".*$",Pattern.CASE_INSENSITIVE);
					}
					query.filter(queryParam.getAttributeName(), pattern).order("-place");
				}
			}
		}
		return query;
	}
	
	
	/**
	 * 创建精确检索query
	 * @param clazz
	 * @param queryParams
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private Query createExactQuery(Class clazz,List<MongoQueryParam> queryParams){
		this.initDatastore();
		Query query = ds.createQuery(clazz);
		if(queryParams!=null){
			for(MongoQueryParam queryParam : queryParams){
				query.filter(queryParam.getAttributeName(), queryParam.getQueryContent());
			}
		}
		return query;
	}

}
